package com.yan.utils;


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.*;
import java.net.*;
import java.util.Base64;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
 * @ClassName: HttpUtil
 * @Description: HTTP CLIENT类用于发送HTTP请求
 */
public class HttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    /**
     * 连接超时 （单位：秒）
     */
    private static final int CONNECTION_TIME_OUT = 30;

    /**
     * 读取数据超时 （单位：秒）
     */
    private static final int READ_TIME_OUT = 60;

    private HttpUtil() {

    }

    public static URLConnection setHttpProxy(String url, String ip, int port) throws IOException {
        URL u = new URL(url);
        InetSocketAddress addr = new InetSocketAddress(ip, port);
        Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
        return u.openConnection(proxy);
    }


    public static String getConnectionResult(String strURL, Map<String, String> params, String method, String charSet) {
        String line = "";
        HttpURLConnection httpConn = null;
        InputStreamReader input = null;
        BufferedReader bufReader = null;
        try {
            strURL += getUrlParam(params, charSet);
            logger.info(strURL);
            URL url = new URL(strURL);
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setConnectTimeout(1000 * CONNECTION_TIME_OUT);// 设置连接主机超时（单位：毫秒）
            httpConn.setReadTimeout(1000 * READ_TIME_OUT);// 设置从主机读取数据超时（单位：毫秒）
            httpConn.setRequestProperty("Accept-Encoding", "");//设置为空的时候,返回的数据也不会乱码
            httpConn.setRequestMethod(method);
            input = new InputStreamReader(httpConn.getInputStream(), charSet);
            bufReader = new BufferedReader(input);

            StringBuilder contentBuf = new StringBuilder();
            while ((line = bufReader.readLine()) != null) {
                contentBuf.append(line);
            }
            String result = contentBuf.toString();
            return result;
        } catch (Exception e) {
            logger.error("【异常】从远程获取数据", e);
            return "";
        } finally {
            try {

                IOUtils.closeQuietly(bufReader);
                IOUtils.closeQuietly(input);

                if (httpConn != null) {
                    httpConn.disconnect();// 断开连接
                    httpConn = null;
                }
            } catch (Exception e2) {
                logger.error(e2.getMessage());
            }
        }
    }

    /*
     * Accept-Encoding 直接使用GZIPInputStream,否则中文乱码
     */
    public static String getZipConnectionResult(String strURL, Map<String, String> params, String method,
                                                String charSet) {
        String line;
        HttpURLConnection httpConn = null;
        InputStreamReader input = null;
        BufferedReader bufReader = null;
        GZIPInputStream gzipInputStream = null;
        try {
            strURL += getUrlParam(params, charSet);
            URL url = new URL(strURL);
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setConnectTimeout(1000 * CONNECTION_TIME_OUT);// 设置连接主机超时（单位：毫秒）
            httpConn.setReadTimeout(1000 * READ_TIME_OUT);// 设置从主机读取数据超时（单位：毫秒）
            httpConn.setRequestProperty("Accept-Encoding", "gzip");
            gzipInputStream = new GZIPInputStream(httpConn.getInputStream());
            input = new InputStreamReader(gzipInputStream, "UTF-8");
            bufReader = new BufferedReader(input);
            StringBuffer buffer = new StringBuffer();

            while ((line = bufReader.readLine()) != null) {
                buffer.append(line);
            }

            return buffer.toString();
        } catch (Exception e) {
            logger.error("【异常】从远程获取数据", e);
            return "";
        } finally {
            try {

                IOUtils.closeQuietly(bufReader);
                IOUtils.closeQuietly(gzipInputStream);
                IOUtils.closeQuietly(input);
                if (httpConn != null) {
                    httpConn.disconnect();// 断开连接
                    httpConn = null;
                }
            } catch (Exception e2) {
                logger.error(e2.getMessage());
            }
        }
    }

    public static String getUrlParam(Map<String, String> params, String charSet) {
        StringBuffer url = new StringBuffer();
        // 组装参数
        if (params != null && !params.isEmpty()) {
            url.append("?");
            for (String key : params.keySet()) {
                try {
                    if (!StringUtils.isEmpty(params.get(key))) {
                        url.append(key + "=" + URLEncoder.encode(params.get(key).toString(), charSet) + "&");
                    } else {
                        url.append(key + "=&");
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            url.deleteCharAt(url.length() - 1);
        }
        return url.toString();
    }


    public static JSONObject getResponseContent(String url, String key, String requestBody) throws Exception {
        logger.info("midtrans url:{} requestBody:{}", url, requestBody);
        URL requestUrl;
        PrintWriter writer = null;

        int code = 0;
        try {
            String basicContent = Base64.getEncoder().encodeToString((key + ":").getBytes("UTF-8"));
            String authorization = String.format("Basic %s", basicContent);

            requestUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection();
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");
            connection.setRequestProperty("Authorization", authorization);

            boolean flag = StringUtils.isEmpty(requestBody);

            if (!flag) {
                connection.setDoOutput(true);
                connection.setDoInput(true);     // 设置是否从httpUrlConnection读入，默认情况下是true;
                writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "utf-8"));
                writer.write(requestBody);
                writer.flush();
            } else {
                connection.setDoInput(true);     // 设置是否从httpUrlConnection读入，默认情况下是true;
            }

            connection.setConnectTimeout(30 * 1000); // 设置一个指定的超时值（以毫秒为单位）
            connection.setReadTimeout(30 * 1000);// 将读超时设置为指定的超时，以毫秒为单位。

            code = connection.getResponseCode();
            String content;
            if (code >= HttpURLConnection.HTTP_OK && code < HttpURLConnection.HTTP_MULT_CHOICE) {
                content = IOUtils.toString(new BufferedReader(new InputStreamReader(connection.getInputStream())));


                return JSONObject.parseObject(content);
            } else {
                String errorMsg = connection.getResponseMessage();
                content = IOUtils.toString(new BufferedReader(new InputStreamReader(connection.getErrorStream())));
                logger.info("url:{} errorInfo:{}", url, content);
                throw new Exception(String.format("request url failed: %s , status:%d, msg:%s", url, code, errorMsg));
            }

        } catch (Exception e) {
            logger.error("midtrans url:{},param:{},statusCode:{},errorMsg:{}", url, requestBody, code, e.getMessage());
            throw e;
        } finally {
            com.alibaba.fastjson.util.IOUtils.close(writer);
        }

    }


}
